<template>
  <div class="point-box">
    <el-dialog
      ref="dialog"
      append-to-body
      :close-on-click-modal="false"
      :title="formTitle"
      fullscreen
      :visible.sync="dialogShow"
      width="1040px"
    >
      <br />
      <div>
        iconArr{{ iconArr }} initArr{{ initArr }} imgX:{{ imgX }} imgY:
        {{ imgY }}imgScale:{{ imgScale }}
        <div class="manager_detail">
          <canvas id="canvas" ref="canvas" class="map" width="1000" height="700"></canvas>
          <div class="operate-box">
            <el-button @click="magnifyFn">+</el-button>
            <el-button @click="shrinkFn" style="margin-right: 40px">-</el-button>
            <el-switch
              style="margin-right: 20px"
              v-model="pointType"
              active-text="点"
              inactive-text="区域"
            >
            </el-switch>
            <el-button @click="clearCanvas" style="margin-left: 20px" type="danger"
              >清除</el-button
            >
            <el-button @click="submit" style="float: right" type="primary"
              >提交</el-button
            >
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import ycMapImg from "@/assets/images/yc.png";
import addIcon from "@/assets/logo/logo.png";
import Vue from "vue";

export default {
  props: ["dialogShow", "formTitle"],
  components: {},
  data() {
    return {
      pointType: true, // true :点 false : 区域
      ycMapImg,
      canvas: null,
      context: null,
      img: null,
      addIcon,
      icon: addIcon,
      iconArr: [],
      resPosArr: [],
      initArr: [],
      imgX: 0,
      imgY: 0,
      addIconX2: 0,
      addIconX: "",
      addIconY2: 0,
      addIconY: "",
      imgScale: 1,
      panning: false,
      isEnd: false,
    };
  },
  methods: {
    clearCanvas() {
      this.iconArr = [];
      this.resPosArr = [];
      this.initArr = [];
      this.isEnd = false;
      this.loadImg();
    },
    /*-----初始化画布获取canvas节点-----*/
    formatMap() {
      this.canvas = document.getElementById("canvas");
      this.context = this.canvas.getContext("2d");
      this.isEnd = false;
      document.getElementById("canvas").addEventListener("contextmenu", (event) => {
        event.preventDefault();
        if (this.pointType) {
          return;
        }

        if (this.iconArr.length < 3) {
          this.$message.error("至少绘制3个点");
          return;
        }
        if (this.isEnd) return;
        this.iconArr.push(this.iconArr[0]);
        this.drawLine(this.iconArr);
        this.isEnd = true;
      });
      this.loadImg();
    },
    /*-----载入图片方法-----*/
    loadImg() {
      this.canvasWidth = this.canvas.width; // canvas画布宽度
      this.canvasHeight = this.canvas.height; // canvas互补画布
      let this_ = this;
      this.img = new Image();
      this.img.onload = function () {
        this_.imgIsLoaded = true;
        console.log(this_.img.width);
        // this_.imgWidthHeightRatio = this_.img.width/this_.img.height; 原计划是画布宽高比根据所上传的图片确定修改为固定比例
        this_.ratioImgCanvas = this_.img.width / this_.canvasWidth; // 图片的宽度/canvas画布宽度
        this_.ratioImgCanvas1 = this_.img.height / this_.canvasHeight; // 图片的高度/canvas画布高度

        for (let i = 0; i < this_.resPosArr.length; i++) {
          // resPosArr 为后端取来的坐标数组 longitude 横坐标x，latitude 纵坐标y，包含一些其他相机数据
          this_.initArr[i] = {}; // 初始化原有坐标集合，相对背景定位 eg：[{x:110,y:110},{x:220,y:220},{x:330,y:330},{x:110,y:69}];
          this_.initArr[i].x = this_.resPosArr[i].longitude / this_.ratioImgCanvas; // 根据 图片与canvas宽高比换算出，当图片平铺在canvas上时，坐标在canvas上的坐标，方便绘图函数绘制坐标为位置，（放大缩小时需要原有坐标，该数组值不会根据惭怍变化而变化，放大缩小或者拖动）。
          this_.initArr[i].y = this_.resPosArr[i].latitude / this_.ratioImgCanvas1;
        }
        console.log(this_.initArr);
        for (let k = 0; k < this_.initArr.length; k++) {
          // iconArr 绘图函数绘图时坐标为位置，放大缩小/拖动，坐标在canvas上的坐标会一直变化（相对背景图片不会变化）
          this_.iconArr[k] = {};
          this_.iconArr[k].x = this_.initArr[k].x;
          this_.iconArr[k].y = this_.initArr[k].y;
        }
        this_.drawImageCanvas(); // 调用绘图函数
      };
      this.img.src = this.ycMapImg; //矢量图
      /*icon图片对象*/
      this.icon = new Image();
      this.icon.onload = function () {
        this_.iconIsLoaded = true;
        this_.drawImageCanvas();
      };
      this.icon.src = this.addIcon; // 地图上原有的图标
      this.addIcon = new Image();
      this.addIcon.onload = function () {};
      this.addIcon.src = this.addIcon; // 地图上新增的图标
      console.log(this.addIcon);
    },
    /*-----绘图函数-----*/
    drawImageCanvas(x, y) {
      console.log("执行次数");
      console.log(this.context.drawImage);
      this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); // 清空背景
      // 画背景
      this.context.drawImage(
        this.img,
        0,
        0,
        this.img.width,
        this.img.height,
        this.imgX,
        this.imgY,
        this.canvas.width * this.imgScale,
        this.canvas.height * this.imgScale
      );
      for (let i = 0; i < this.iconArr.length; i++) {
        this.drawDot({ x: this.iconArr[i].x, y: this.iconArr[i].y });
        // this.context.drawImage(
        //   this.icon,
        //   this.iconArr[i].x - 16,
        //   this.iconArr[i].y - 16,
        //   32,
        //   32
        // ); // 画原有坐标（坐标集合）
      }
      /*未点击新增坐标时，不绘制新增icon*/
      // console.log(this.context);
      if (x !== undefined && y !== undefined && x !== "" && y !== "") {
        // this.context.drawImage(this.addIcon, x - 16, y - 16, 32, 32); // 画新增坐标
      } else if (this.addIconX !== "" && this.addIconY !== "") {
        // this.context.drawImage(
        //   this.addIcon,
        //   this.addIconX - 16,
        //   this.addIconY - 16,
        //   32,
        //   32
        // ); // 画新增坐标
      }
    },
    /*-----绘制圆点-----*/
    drawDot(pos, color) {
      // let ctx = this.canvas.getContext("2d");
      this.context.beginPath();
      this.context.closePath();
      this.context.fill();
      this.context.arc(pos.x, pos.y, 4, 0 * Math.PI, 2 * Math.PI);
      this.context.fillStyle = "#f00";
      this.context.fill();
      this.context.stroke();
    },
    drawLine(arr) {
      // if (arr.length === 0) return;
      if (arr.length < 2) {
        return false;
      }
      for (var k = 0; k < arr.length; k++) {
        if (!arr[k + 1]) return;
        this.context.beginPath();
        this.context.strokeStyle = "#f00";
        this.context.lineWidth = "2";
        this.context.moveTo(arr[k].x, arr[k].y);
        this.context.lineTo(arr[k + 1].x, arr[k + 1].y);
        this.context.stroke();
      }
    },
    /*-----鼠标按下/拖动/抬起事件-----*/
    mouseEvent() {
      let this_ = this;
      this.canvas.onmousedown = function (event) {
        if (event.button == 2) {
          return;
        }
        let pos0 = this_.windowToCanvas(this_.canvas, event.clientX, event.clientY); // 调用窗口坐标转canvas坐标函数
        let pos = this_.windowToCanvas(this_.canvas, event.clientX, event.clientY);
        this_.canvas.onmousemove = function (event) {
          let pos1 = this_.windowToCanvas(this_.canvas, event.clientX, event.clientY); // 注：此处为操作逻辑处理，当按下位置在新增坐标上，拖动时 拖动的是新增坐标，背景不会动，否则拖动背景 // 坐标为一个点，画布上以坐标为中心点画一个32px*32px的正方形，这样就有了鼠标按下的判断区间
          /*按下坐标在新增坐标上，拖动坐标位置or拖动背景图片*/ if (
            pos.x > this_.addIconX1 - 16 &&
            pos.x < this_.addIconX1 + 16 &&
            pos.y > this_.addIconY1 - 16 &&
            pos.y < this_.addIconY1 + 16
          ) {
            // 当拖动新增坐标时 ，鼠标位置为新增坐标位置
            this_.addIconX2 = pos1.x;
            this_.addIconY2 = pos1.y;
            this_.drawImageCanvas(this_.addIconX2, this_.addIconY2);
          } else {
            // 鼠标按下的位置在画布上（不在新增坐标上）
            /*鼠标移出canvas画布外=> 禁止拖动*/
            if (
              pos1.x >= this_.canvas.width - 20 ||
              pos1.y >= this_.canvas.height - 20 ||
              pos1.x <= 20 ||
              pos1.y <= 20
            ) {
              this_.canvas.onmousemove = null;
              return false;
            }
            let x = pos1.x - pos.x; // 鼠标按下坐标与移动坐标差值
            let y = pos1.y - pos.y;
            pos = pos1;
            this_.imgX += x;
            this_.imgY += y;
            /*背景拖到边缘时禁止拖动*/
            if (this_.imgX >= 0) {
              this_.imgX = 0;
            }
            if (this_.imgY >= 0) {
              this_.imgY = 0;
            }
            if (-this_.imgX >= this_.canvas.width * this_.imgScale - this_.canvas.width) {
              this_.imgX = -(this_.canvas.width * this_.imgScale - this_.canvas.width);
            }
            if (
              -this_.imgY >=
              this_.canvas.height * this_.imgScale - this_.canvas.height
            ) {
              this_.imgY = -(this_.canvas.height * this_.imgScale - this_.canvas.height);
            }
            // console.log('画布原点',this_.imgX,this_.imgY);
            for (let j = 0; j < this_.iconArr.length; j++) {
              // 坐标集合移动处理 此处为拖动时坐标处理 => 不理解可以在纸上画画，确定坐标数据计算方式
              this_.iconArr[j].x = this_.imgX + this_.initArr[j].x;
              this_.iconArr[j].y = this_.imgY + this_.initArr[j].y;
            }
            this_.drawImageCanvas(this_.addIconX1, this_.addIconY1); // 绘制图片/ 新增坐标相对canvas不变化 addIconX1,在拖动时为定值，拖动时在canvas上的位置没变化
          }
        };
        this_.canvas.onmouseup = function (event) {
          let pos2 = this_.windowToCanvas(this_.canvas, event.clientX, event.clientY);
          this_.canvas.style.cursor = "default";
          this_.canvas.onmousemove = this_.cnvs_getCoordinates; // 鼠标在canvas上越过时触发函数，为实现其他功能暂时忽略
          this_.canvas.onmouseup = null;

          /*鼠标按下抬起时，是否产生移动=》是：拖动事件，否：点击事件*/
          let x1 = pos2.x - pos0.x;
          let y1 = pos2.y - pos0.y;
          if (x1 === 0 && y1 === 0) {
            if (this_.isEnd) return;
            let pos = this_.windowToCanvas(this_.canvas, event.clientX, event.clientY);
            // 点击后将点位存入iconArr中
            // this_.initArr.push(pos);
            // this_.iconArr.push(pos);
            // 绘制点时需要清空数组
            if (this_.pointType) {
              this_.iconArr = [];
              this_.initArr = [];
              this_.loadImg();
            }
            this_.initArr.push({
              x: pos.x - this_.imgX,
              y: pos.y - this_.imgY,
            });
            this_.iconArr.push(pos);
            this_.drawDot(pos);
            this_.drawLine(this_.iconArr);
            for (let i = 0; i < this_.iconArr.length; i++) {
              if (
                pos2.x >= this_.iconArr[i].x - 16 &&
                pos2.x <= this_.iconArr[i].x + 16 &&
                pos2.y >= this_.iconArr[i].y - 16 &&
                pos2.y <= this_.iconArr[i].y + 16
              ) {
                // this_.handleCanvasIconClick(i, pos2); // 点击时 当点击在原有坐标上可进行修改操作调用函数 暂时忽略
              }
            }
          } else {
            console.log("拖动事件");
            /*当拖动新增坐标时，鼠标移动最终位置位置，为新增坐标最终位置 => 注意点*/
            if (
              pos.x > this_.addIconX1 - 16 &&
              pos.x < this_.addIconX1 + 16 &&
              pos.y > this_.addIconY1 - 16 &&
              pos.y < this_.addIconY1 + 16
            ) {
              this_.addIconX1 = this_.addIconX2;
              this_.addIconY1 = this_.addIconY2;
            }
            this_.drawLine(this_.iconArr);
          }
        };
      };
    },

    /*-----点击放大按钮->以中心点放大-----*/
    // 放大方法图片是以中心点放大 缩小同理，计算方式比较简单
    magnifyFn() {
      // this.alertMsgBox.style.display = "none";
      if (this.imgScale < 3.6) {
        this.imgScale *= 1.2;
        this.imgX = (this.canvas.width - this.canvas.width * this.imgScale) / 2;
        this.imgY = (this.canvas.height - this.canvas.height * this.imgScale) / 2; // 放大缩小需处理 原有坐标集合，注意点
        for (let i = 0; i < this.initArr.length; i++) {
          console.log(this.initArr[i].x, "1");
          Vue.set(this.initArr, i, {
            x: this.initArr[i].x * 1.2,
            y: this.initArr[i].y * 1.2,
          });
          // this.initArr[i].x = this.initArr[i].x * 1.2;
          // this.initArr[i].y = this.initArr[i].y * 1.2;
          console.log(this.initArr[i].x, "2");
        }
        for (let j = 0; j < this.iconArr.length; j++) {
          Vue.set(this.iconArr, j, {
            x: this.imgX + this.initArr[j].x,
            y: this.imgY + this.initArr[j].y,
          });
          // this.iconArr[j].x = this.imgX + this.initArr[j].x;
          // this.iconArr[j].y = this.imgY + this.initArr[j].y;
        }
        this.drawImageCanvas(this.addIconX2, this.addIconY2);
        this.drawLine(this.iconArr);

        return false;
      } else {
        this.$alert("已经最大了", {
          confirmButtonText: "确定",
          center: true,
        });
      }
    },
    /*-----点击缩小按钮，以中心点缩小-----*/
    shrinkFn() {
      // this.alertMsgBox.style.display = "none";
      if (this.imgScale > 1) {
        this.imgScale /= 1.2;
        this.imgX = (this.canvas.width - this.canvas.width * this.imgScale) / 2;
        this.imgY = (this.canvas.height - this.canvas.height * this.imgScale) / 2;

        for (let i = 0; i < this.initArr.length; i++) {
          this.initArr[i].x = this.initArr[i].x / 1.2;
          this.initArr[i].y = this.initArr[i].y / 1.2;
        }
        for (let j = 0; j < this.iconArr.length; j++) {
          this.iconArr[j].x = this.imgX + this.initArr[j].x;
          this.iconArr[j].y = this.imgY + this.initArr[j].y;
        }
        this.drawImageCanvas(this.addIconX2, this.addIconY2);
        this.drawLine(this.iconArr);

        // console.log('画布原点',this.imgX,this.imgY);
      } else {
        this.$alert("已经最小了", {
          confirmButtonText: "确定",
          center: true,
        });
      }
      return false;
    },

    /*-----选择相机后新增坐标-----*/
    // 点击新增坐标按钮后，新增坐标初始位置在canvas画布中心
    addBtnClick() {
      this.addIconX = this.canvas.width / 2;
      this.addIconY = this.canvas.height / 2;
      this.drawImageCanvas(this.addIconX, this.addIconY);
      this.addIconX1 = this.addIconX;
      this.addIconY1 = this.addIconY;
    },
    /*-----关联相机页面-点击保存按钮-----*/
    submit() {
      // console.log(this.locationMapDetail);
      //if (this.locationMapDetail.img == null) {
      //this.$alert('该区位暂未上传图片，请先上传图片', {
      //confirmButtonText: '确定',
      //center:true
      //});
      //return
      //}
      console.log("当前放大倍数", this.imgScale);

      // 前面对于新增坐标的处理，坐标都是 新增坐标点在canvas上的位置，保存时需要通过计算，得到该坐标在背景图片的位置，保存的也将是计算得来的坐标值。
      // 计算这里我是分为两步，稍微有点绕，其实仔细想想也并不难，需多在纸上画画计算一下。
      // this.fx = (this.addIconX1 - this.imgX) / this.imgScale;
      // this.fy = (this.addIconY1 - this.imgY) / this.imgScale;
      // console.log(this.fx, this.fy);
      // this.sx = (this.fx * this.img.width) / this.canvas.width;
      // this.sy = (this.fy * this.img.height) / this.canvas.height;
      // alert("保存的坐标点为" + this.sx + " : " + this.sy);
      while (this.imgScale > 1) {
        console.log(this.imgScale);
        this.shrinkFn();
      }
      // let arr = this.iconArr.map((item) => {
      //   return {
      //     x: item.x / this.imgScale - this.imgX,
      //     y: item.y / this.imgScale - this.imgY,
      //   };
      // });
      console.log(this.imgScale, "!!!");
      this.$post(
        this.baseUrl +
          " 后端接口 ?locationId=" +
          this.selectedMapId +
          "&cameraId=" +
          this.selectedCameraId +
          "&longitude=" +
          this.sx +
          "&latitude=" +
          this.sy
      ).then((res) => {
        console.log(res);
        if (res.data.code === "200" && res.data.msg === "success") {
          this.$notify.success({
            message: "保存成功",
            offset: 600,
          });
          /*保存成功重新载入地图*/
          this.initArr = [];
          this.$fetch(
            this.baseUrl +
              "/接口地址/" +
              this.selectedMapId +
              "?withBlob=true&enableCoordinate=true"
          ).then((res) => {
            console.log(res);
            if (res.data.img == null) {
              this.imgSrc = "../../../../static/img/map/zhanweitu.png";
            } else {
              this.imgSrc = res.data.img;
            }
            if (res.data.cameraMapResourceDtos != null) {
              this.resPosArr = res.data.cameraMapResourceDtos;
              this.cameraCount = this.resPosArr.length;
            } else {
              this.resPosArr = [];
              this.cameraCount = this.resPosArr.length;
            }
          });
        } else {
          this.$notify({
            message: "保存失败",
            offset: 600,
            type: "warning",
          });
        }
      });
    },
    /*-----window坐标转canvas坐标-----*/
    windowToCanvas(canvas, x, y) {
      let bbox = canvas.getBoundingClientRect();
      return {
        x: x - bbox.left - (bbox.width - canvas.width) / 2,
        y: y - bbox.top - (bbox.height - canvas.height) / 2,
      };
    },
  },
  created() {},
  mounted() {
    this.$nextTick(() => {
      this.formatMap();
      this.mouseEvent();
    });
  },
  watch: {
    pointType() {
      this.clearCanvas();
      this.isEnd = false;
    },
  },
};
</script>
<style scoped>
.manager_detail {
  width: 100%;
  height: calc(100vh - 112px);
  overflow: hidden;
  text-align: center;
}
.map {
  border: 1px solid #898989;
  width: 1000px;
  margin: 0 auto;
}
.operate-box {
  width: 1000px;
  margin: 0 auto;
  text-align: left;
}
</style>
